#include "Col.ph"
#ifdef __GNUG__
#pragma implementation
#endif

#include "PathLookup.h"

#include "Class.h"
#include "ByteArray.h"
#include "OrdColl.h"
#include "System.h"
#include "String.h"
#include "Env.h"
#include "Symbol.h"
#include "ET_stdio.h"

//---- PathLookup --------------------------------------------------------------

NewMetaImpl(PathLookup,Object, (TP(path), TP(paths)));

PathLookup::PathLookup(const char *p)
{
	path= strsave(p);
	paths= 0;
	Scan();
}

PathLookup::PathLookup(const Symbol &s)
{
	path= strsave(Env::GetValue(s.AsString(), "."));
	paths= 0;
	Scan();
}

PathLookup::~PathLookup()
{
	SafeDelete(path);
	if (paths)
		paths->FreeAll();
	SafeDelete(paths);
}

bool PathLookup::Lookup(const char *name, char *buf, int access)
{
	if (*name == '/') {
		if (gSystem->AccessPathName(name, access) == 0) {
			strcpy(buf, name);
			return TRUE;
		}
	}
	
	if (!paths)
		return FALSE;
	Iter next(paths);
	ByteArray *bp;
	while (bp= (ByteArray*)next()) {
		sprintf(buf, "%s/%s", bp->Str(), name);
		//fprintf(stderr, "Lookup: %s\n", buf);
		if (gSystem->AccessPathName(buf, access) == 0)
			return TRUE;
	}
	return FALSE;
}

void PathLookup::Scan()
{
	register char *p= path;

	for (p= path; p && *p;) {
		if (*p)
			Add(p);
		for (; *p; p++)
			if (*p == ':') {
				p++;
				break;
			}
	}
}

void PathLookup::Add(const char *p)
{
	char buf[1000];
	register char *q;

	for (q= buf;;) {
		switch (*p) {
		case '%':
			p++;
			switch (*p++) {
			case 'e':
				strcpy(q, gEtDir);
				q+= strlen(gEtDir);
				break;
			default:
				break;
			}
			break;
		case ':':
		case '\0':
			{
			*q= '\0';
			gSystem->ExpandPathName(buf, sizeof buf);
			//fprintf(stderr, "Add(%s)\n", buf);
			ByteArray *b= new ByteArray(buf);
			if (paths == 0) 
				paths= new OrdCollection(4);
			if (!paths->Contains(b))
				paths->Add(b);
			else {
				SafeDelete(b);
			}
			}
			return;
		default:
			*q++= *p++;
			break;
		}
	}
}

